#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100
#define EMPTY 0
#define NOT_EMPTY 1
typedef int Status;
typedef int QElemType;

typedef struct QueueNode{
    QElemType data;
    struct QueueNode *next;
}QueueNode;

typedef QueueNode *LinkQueue;

void opSystem(LinkQueue *Q);

Status initQueue(LinkQueue *Q);
Status checkTheQueue(LinkQueue Q);
Status getHead(LinkQueue Q,QElemType *elem);
Status enQueue(LinkQueue *Q,QElemType enter);
Status deQueue(LinkQueue *Q,QElemType *delete);
Status DestroyQueue(LinkQueue *Q);
Status ClearQueue(LinkQueue *Q);
Status QueueEmpty(LinkQueue Q);
Status QueueLength(LinkQueue Q);


int main() {
    setbuf(stdout,NULL);
    LinkQueue Q;
    initQueue(&Q);
    opSystem(&Q);
    return 0;
}

void opSystem(LinkQueue *Q) {
    int operation = 0;
    QElemType data;
    printf("----------------------------------------------------------\n");
    printf("Please select what you want to do to the Queue:\n");
    printf("1 :check the Queue if you have initialized one\n");
    printf("2 :get the head elem of this Queue\n");
    printf("3 :enter a elem to this Queue\n");
    printf("4 :delete the head elem of this Queue\n");
    printf("5 :get the length of the Queue\n");
    printf("0 :reinitialize the Queue\n");
    printf("-1 :Clear the Queue\n");
    printf("-2:Destroy the Queue\n");
    printf("----------------------------------------------------------\n");
    scanf("%d",&operation);
    switch (operation) {
        case 1:
            checkTheQueue(*Q);
            opSystem(Q);
            break;
        case 2:
            getHead(*Q,&data);
            opSystem(Q);
            break;
        case 3:
            enQueue(Q,101);
            opSystem(Q);
            break;
        case 4:
            deQueue(Q,&data);
            opSystem(Q);
            break;
        case 5:
            QueueLength(*Q);
            opSystem(Q);
            break;
        case 0:
            initQueue(Q);
            opSystem(Q);
            break;
        case -1:
            ClearQueue(Q);
            printf("Queue has been cleared.\n");
            opSystem(Q);
            break;
        case -2:
            DestroyQueue(Q);
            printf("Queue has been destroyed,program will exit soon.\n");
            break;
        default:
            break;
    }
}
//初始化队列，仍然是随机赋值
Status initQueue(LinkQueue *Q) {
    printf("Please initialize the LinkList,you may enter the length of it(default is 100,and no longer than 100):\n");
    int length = MAXSIZE;
    scanf("%d",&length);
    if (length > 100) length = 100;
    LinkQueue p,q;
    srand(time(0));
    (*Q) = (LinkQueue) malloc(sizeof(QueueNode));
    (*Q)->next = NULL;
    q = (*Q);
    for (int i = 0; i < length; ++i) {
        p = (LinkQueue) malloc(sizeof(QueueNode));
        p -> next = NULL;
        p -> data = rand() % 100 + 1;
//        p->data = i;
        q -> next = p;
        q = p;
    }
    (*Q)->data = length;
    printf("Queue initialize successfully!\n");
    checkTheQueue(*Q);
    return OK;
}
//查看队列所有元素（虽然实际操作应该不会这么干，这个函数是为了方便查看队的结构和内部数据）
Status checkTheQueue(LinkQueue Q) {
    if (Q->next == NULL) return ERROR;
    printf("now the Queue is below:\n");
    printf("Head [ ");
    LinkQueue p = Q->next;
    while (p) {
        printf("%d ",p->data);
        p = p -> next;
    }
    printf("] Tail\n");
    return OK;
}
//获取队首元素
Status getHead(LinkQueue Q,QElemType *elem) {
    if (Q -> next == NULL) return ERROR;
    LinkQueue p = Q -> next;
    *elem = p -> data;
    printf("the head elem of this Queue is %d\n",*elem);
    return OK;
}
//新增一个元素到队尾
Status enQueue(LinkQueue *Q,QElemType enter) {
    if ((*Q) == NULL) return ERROR;
    LinkQueue p = (LinkQueue) malloc(sizeof(QueueNode)),q = (*Q);
    p -> data = enter;
    p -> next = NULL;
    while (q -> next) {
        q = q -> next;
    }
    q -> next = p;
    (*Q) -> data++;
    checkTheQueue(*Q);
    return OK;
}
//队首元素出队
Status deQueue(LinkQueue *Q,QElemType *delete) {
    if ((*Q)->next == NULL) return ERROR;
    LinkQueue p = (*Q) -> next;
    *delete = p -> data;
    (*Q)->next = p -> next;
    free(p);
    printf("the head elem %d of this Queue will be deleted\n",*delete);
    (*Q) -> data--;
    checkTheQueue(*Q);
    return OK;
}
//如果队列存在，则销毁队列
Status DestroyQueue(LinkQueue *Q){
    if ((*Q)->next == NULL) return ERROR;
    printf("Warning:You are going to destroy the Queue you have created!\nAre you sure to continue?\n");
    printf("1:YES,0:NO\n");
    int judge = 0;
    scanf("%d",&judge);
    if (judge == 0) {
        printf("destroy canceled\n");
        return FALSE;
    }
    LinkQueue p,r;
    p = (*Q) -> next;
    while (p) {
        r = p -> next;
        free(p);
        p = r;
    }
    (*Q) -> next = NULL;
    free((*Q));
    printf("Destroy successfully!\n");
    return OK;
}
//清空队列，将其元素全部置成0
Status ClearQueue(LinkQueue *Q){
    if ((*Q)->next == NULL) return ERROR;
    printf("Warning:You are going to clear the Queue you have created!\nAre you sure to continue?\n");
    printf("1:YES,0:NO\n");
    int judge = 0;
    scanf("%d",&judge);
    if (judge == 0) {
        printf("clear canceled\n");
        return FALSE;
    }
    LinkQueue p,r;
    p = (*Q) -> next;
    while (p) {
        r = p -> next;
        p -> data = 0;
        p = r;
    }
    printf("clear successfully!\n");
    checkTheQueue(*Q);
    return OK;
}
//判断队列是否为空
Status QueueEmpty(LinkQueue Q) {
    if (Q->next == NULL) return EMPTY;
    else return NOT_EMPTY;
}
//获取队列长度
Status QueueLength(LinkQueue Q) {
    printf("the length of this Queue is %d\n",Q->data);
    return Q->data;
}